package cn.edu.sjtu.se.dslab.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.edu.sjtu.se.dslab.action.bean.PageBean;
import cn.edu.sjtu.se.dslab.auth.User;
import cn.edu.sjtu.se.dslab.component.design.DesignPattern;
import cn.edu.sjtu.se.dslab.component.design.DesignPatternComponent;
import cn.edu.sjtu.se.dslab.component.design.DesignPatternInstance;
import cn.edu.sjtu.se.dslab.component.design.DesignPatternType;
import cn.edu.sjtu.se.dslab.component.dp.parse.DesignPatternInstanceBean;
import cn.edu.sjtu.se.dslab.component.dp.parse.Property;
import cn.edu.sjtu.se.dslab.dao.IComponentDao;
import cn.edu.sjtu.se.dslab.dao.IDesignPatternComponentDao;
import cn.edu.sjtu.se.dslab.dao.IDesignPatternInstanceDao;
import cn.edu.sjtu.se.dslab.exception.DBException;
import cn.edu.sjtu.se.dslab.project.Project;
import cn.edu.sjtu.se.dslab.service.IDesignPatternComponentService;
import cn.edu.sjtu.se.dslab.service.IDesignPatternService;
import cn.edu.sjtu.se.dslab.util.Const;
import cn.edu.sjtu.se.dslab.util.MD5;

import com.sun.jmx.snmp.Timestamp;


/**
 * 
 * @author longshaohang
 *
 */
@Service("designPatternComponentService")
@Transactional
public class DesignPatternComponentServiceImpl implements IDesignPatternComponentService {


	@Resource(name="designPatternComponentDao")
	private IDesignPatternComponentDao designPatternComponentDao;

	@Resource(name="designPatternInstanceDao")
	private IDesignPatternInstanceDao designPatternInstanceDao;

	@Resource(name="componentDao")
	private IComponentDao componentDao;
	
	@Resource(name="designPatternService")
	private IDesignPatternService designPatternService;

	@Override
	public boolean addDesignPatternComponent(DesignPatternComponent designPatternComponent) {
		DesignPatternInstance instance = designPatternComponent.getInstance();
		instance.setCreateTime(new Date());
		designPatternInstanceDao.save( instance);
		designPatternComponent.setCreateTime(new Date());
		designPatternComponent.setLastModified(new Date());
		designPatternComponentDao.save(designPatternComponent);

		MD5 md5 = new MD5();
		String num = null;
		do{
			StringBuffer s = new StringBuffer();
			s.append(instance.getName());
			s.append(new Timestamp().toString());
			num = md5.getMD5ofStr(s.toString()).substring(0, 8);
		}while(!componentDao.checkUri(num));
		
		String uri = toDesignPatternComponentUri(
				instance.getDesignPattern().getType().toString(), num);
		
		designPatternComponent.setUri(uri);
		designPatternComponentDao.save(designPatternComponent);
		//create xml file
		DesignPatternInstanceBean dpiBean = new DesignPatternInstanceBean(
				designPatternComponent.getName(), instance.getDesignPattern().getType());
		dpiBean.save(designPatternComponent.getXmlPath());
		return true;
	}
	
	@Override
	public boolean addAllDesignPatternComponent(Project project){
		List<DesignPattern> dps = designPatternService.getDesignPatternList();
		User user = project.getOwner();
		for (DesignPattern dp : dps){
			DesignPatternInstance dpi = new DesignPatternInstance();
			DesignPatternComponent dpc = new DesignPatternComponent();
			String dpType = dp.getType().toString();
			StringBuffer sb = new StringBuffer( project.getName() ); 
			dpi.setName( sb.append("-").append( dpType ).toString() );
			dpi.setDesignPattern(dp);
			dpi.setComponent(dpc);
			
			dpc.setInstance(dpi);
			dpc.setOwner(user);
			dpc.setType(dpType);
			dpc.setName(dpi.getName());
			dpc.setProject(project);
			StringBuffer sb2 = new StringBuffer(project.getFolderPath());
			sb2.append(project.getName()).append(".").append(dpType).append(".xml");
			dpc.setXmlPath( sb2.toString() );
			
			addDesignPatternComponent(dpc);
		}
		return true;
	}
	
//	@Override
//	public void deleteBusDpcItem(String itemName, String itemValue, String dpcUri){
//		DesignPatternComponent dpc = designPatternComponentDao.queryByUri(dpcUri);
//		DesignPatternInstanceBean dpiBean = new DesignPatternInstanceBean(DesignPatternType.BUS, dpc.getXmlPath());
//		dpiBean.deleteInstanceByName(itemName,itemValue);
//		dpiBean.save(dpc.getXmlPath());
//	}
	
	@Override
	public void deleteDpcItem(String itemName, String itemValue, String dpcUri){
		DesignPatternComponent dpc = designPatternComponentDao.queryByUri(dpcUri);
		DesignPatternInstanceBean dpiBean = new DesignPatternInstanceBean(
				DesignPatternType.valueOf(dpc.getType().toUpperCase()), dpc.getXmlPath());
		dpiBean.deleteInstanceByName(itemName,itemValue);
		dpiBean.save(dpc.getXmlPath());
	}
	
	
	
	@Override
	public void addDpcItem(Map<String, String> propertyMap, String dpcUri){
		DesignPatternComponent dpc = designPatternComponentDao.queryByUri(dpcUri);
		DesignPatternInstanceBean dpiBean = new DesignPatternInstanceBean(
				DesignPatternType.valueOf(dpc.getType().toUpperCase()), dpc.getXmlPath());
		Map<String, Property> instance = new HashMap<String, Property>();
		for (Entry<String, String> entry : propertyMap.entrySet()){
			Property p = new Property();
			p.setName(entry.getKey());
			p.setValue(entry.getValue());
			instance.put(entry.getKey(), p);
		}
		Property idProperty = new Property();
		idProperty.setName("id");
		int newMaxId = dpiBean.getMaxId() + 1;
		idProperty.setValue( String.valueOf(newMaxId));
		dpiBean.setMaxId(newMaxId);
		instance.put("id", idProperty);
		dpiBean.getInstances().add(instance);
		dpiBean.save(dpc.getXmlPath());
	}
	
	
	@Override
	public DesignPatternInstanceBean getDesignPatternInstanceBean(String uri){
		DesignPatternComponent component = designPatternComponentDao.queryByUri(uri);
		//根据名字获取对应的枚举类型
		return new DesignPatternInstanceBean( DesignPatternType.valueOf(component.getType().toUpperCase()),
				component.getXmlPath());
	}

	@Override
	public DesignPatternComponent updateDesignPatternComponent(
			DesignPatternComponent dpComponent) {
		dpComponent.setLastModified(new Date());
		return designPatternComponentDao.update(dpComponent);
	}

	@Override
	public DesignPatternComponent getDesignPatternComponentById(long id) {
		return designPatternComponentDao.queryById(id);
	}

	@Override
	public PageBean getPageBean(int pageNum) throws DBException {
		return null;
	}

	@Override
	public List<DesignPatternComponent> getDesignPatternComponentList() {
		return designPatternComponentDao.queryByList();
	}

	@Override
	public List<DesignPatternComponent> getDesignPatternComponentsByDP(int pgNo, int pgSize, String uri) {
		return designPatternComponentDao.queryListByDesignPattern(pgNo, pgSize, uri.toString());
	}

	@Override
	public DesignPatternComponent getDesignPatternComponentByUri(String uri) {
		return designPatternComponentDao.queryByUri(uri);
	}

	@Override
	public List<DesignPatternComponent> getDesignPatternComponentsByProject(long projectId){
		List<DesignPatternComponent> dpcs = designPatternComponentDao.queryListByProject(projectId);
		return dpcs;
	}
	
	@Override
	public DesignPatternComponent getDesignPatternCommponentByType(long projectId, DesignPatternType dpType){
		return designPatternComponentDao.queryByType(projectId, dpType.toString());
	}

	public static String toDesignPatternComponentUri(String type, String number){
		StringBuffer dpcUri = new StringBuffer(Const.URI_DESIGN_PATTERN_COMPONENT);
		return dpcUri.append(":").append(type).append(":").append(number).toString();
	}




}
